<?php
namespace app\controller;

use app\admin\model\System;
use app\common\Controller;
use app\common\exception\AppinException;
use app\common\exception\AdminException;
use app\appin\validate\AppinValidate;
use app\appin\service\Request;
use app\admin\model\WorkerDepartment;

class App extends Controller
{
    /**
	 * 中间件处理APP请求
	 */
	protected $middleware = [ \app\appin\middleware\Appin::class ];

    /**
     * [插件入口]
     * @param  string $route [插件路由]
     * @return [type]        [description]
     */
    public function index($name, $controller = 'Index', $action = 'index')
	{
        try {

            validate(AppinValidate::class)->check([
                'name' => $name,
                'controller' => $controller,
                'action' => $action
            ]);

            return $this->_call($name, $controller, $action);
        } catch ( \Exception $e ) {
            if ($e instanceof AdminException) {
                throw $e;
            }
            throw new AppinException($e->getMessage());
        }
	}

    /**
     * [_call description]
     * @param  [type] $appinName       [description]
     * @param  [type] $appinController [description]
     * @param  [type] $appinAction     [description]
     * @return [type]                  [description]
     */
    private function _call($appinName, $appinController, $appinAction)
    {
        $appinClass = app()->appin_controller_classed;
        $appinReflectionClass = new \ReflectionClass($appinClass);
        $appinClassObject = $appinReflectionClass->getMethod($appinAction);

        bind('appin', function() use($appinName, $appinController, $appinAction){
            return [
                'name'          => $appinName,
                'controller'    => $appinController,
                'action'        => $appinAction
            ];
        });

        bind('appinRequest', Request::class);

        $system = System::lists();
        bind('system', function() use ($system){
            return $system;
        });


        if ( $this->app->appinRequest->hasAuther() ) {
            $workerId = session('admin.worker.id');
            if ( !$workerId ) {
                return redirect( url('/admin') );
            }
            if ( $workerId != 1) {
                $depart = WorkerDepartment::find(session('admin.worker.depart_id'));
                if (!$depart) {
                    throw new AdminException('您无权限访问!');
                }
                if ( !in_array($this->app->appinRequest->uri, $depart['node_indexs']) ) {
                    throw new AdminException('您无权限访问!');
                }
            }
        }

        $parameters = [];
        foreach( $appinClassObject->getParameters() as $par)
        {
            $className = $par->getClass();
            if ( $className ) $parameters[] = new $className->name;
        }
        return $appinClassObject->invokeArgs(
            $appinReflectionClass->newInstanceArgs( [$this->app] ),
            $parameters
        );
    }
}
